package eu.tsp.isensors.impl.storage;

import eu.tsp.isensors.services.storage.*;

import eu.tsp.isensors.services.index.RunXQuery;

import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URIBuilder;
//import org.apache.http.client.params.ClientPNames;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
//import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;

import java.util.List;
import java.util.ArrayList;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import java.net.URI;
import org.apache.http.client.utils.URLEncodedUtils;
import java.net.URISyntaxException;

class StorageExistDBImpl implements Get, Put, Delete, RunXQuery{

	String db_address;

	public byte[] get (String id){
		HttpClient httpclient = new DefaultHttpClient();
		//Transoformation de l'id
		id = id.replaceAll("_", "/");
        	HttpGet httpget = new HttpGet(db_address+id);
		try {
			byte[] b = EntityUtils.toByteArray(httpclient.execute(httpget).getEntity());
            		return b;
        	} catch (ClientProtocolException ex) {
			ex.printStackTrace();
        	} catch (IOException ex) {
			ex.printStackTrace();
        	}
		return null;
	}
	public String get_as_string(String id){
		return new String(get(id));
	}
	public String put(String collection, String mimeType, byte[] data, String name){
		String t_uri =  collection+"/"+name;
		return put(t_uri, mimeType, data);
	}
	public String put(String dataID, String mimeType, byte[] data){
		//Si cette méthode a été appelé avec un identifiant, cette opération est nécessaire 
		//sinon elle ne sert à rien
		String uri = null,
		       t_uri = dataID.replaceAll("_", "/");
		
		//Vérifier qu'à la fin de l'id, il n'y a pas de "/"
		//A faire si nécessaire
		
		ByteArrayEntity myEntity = new ByteArrayEntity(data);
		if(mimeType != null && !mimeType.equals("")){
			myEntity.setContentType(mimeType);
		}
		HttpPut httpput = new HttpPut(db_address+t_uri);
		httpput.setEntity(myEntity);
		HttpClient httpclient = new DefaultHttpClient();
		HttpResponse response;
		try {
			response = httpclient.execute(httpput);
			HttpEntity responseEntity = response.getEntity();
			if (responseEntity != null) {
				uri = EntityUtils.toString(responseEntity);
				uri = t_uri.replaceAll("/", "_");//+"_"+uri;
			}
		} catch (ClientProtocolException ex) {
		} catch (IOException ex) {
		}
		return uri;
	}
	public String put(String dataID, byte[] data){
		return put(dataID, "", data);
	}
	
	public byte[] delete(String id){
		HttpClient httpclient = new DefaultHttpClient();
		//Transoformation de l'id
		id = id.replaceAll("_", "/");
        	HttpDelete httpDelete = new HttpDelete(db_address+id);
		try {
			byte[] b = EntityUtils.toByteArray(httpclient.execute(httpDelete).getEntity());
            		return b;
        	} catch (ClientProtocolException ex) {
			ex.printStackTrace();
        	} catch (IOException ex) {
			ex.printStackTrace();
        	}
		return null;
	}
	
	public byte[] execScript(String nodeID, String memory, String data_id, String scriptID, String configID){
		PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
        	cm.setMaxTotal(100);
		HttpClient httpclient = new DefaultHttpClient(cm);
		//httpclient.getParams().setParameter(ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME, PoolingClientConnectionManager.class.getName());
		System.out.println(" (1) execScript");
		try{
			System.out.println("	try{");
			List<NameValuePair> qparams = new ArrayList<NameValuePair>();
			qparams.add(new BasicNameValuePair("nodeID", nodeID));
			if (! memory.equals("")){qparams.add(new BasicNameValuePair("memory", memory));}
			qparams.add(new BasicNameValuePair("data_id", data_id.replaceAll("_", "/")));
			if (! configID.equals("")){qparams.add(new BasicNameValuePair("configID", configID.replaceAll("_", "/")));}
			
			//URI building
			URIBuilder urib = new URIBuilder(db_address+scriptID.replaceAll("_", "/"));
			//System.out.println("\n"+urib.getHost()+"\n"+urib.getPort()+"\n"+urib.getPath());
			
			//qparams.add(new BasicNameValuePair("uri_api", uri_api));
			URI uri = URIUtils.createURI(urib.getScheme(), urib.getHost(), urib.getPort(), urib.getPath(), URLEncodedUtils.format(qparams, "UTF-8"), null);
			
			// DEBUG
			System.out.println("URI = "+ uri.toString());
			//
                	HttpGet httpget = new HttpGet(uri);
                        HttpEntity entity = httpclient.execute(httpget).getEntity();
			byte[] b = EntityUtils.toByteArray(httpclient.execute(httpget).getEntity());
			return b;
			
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
                } catch (ClientProtocolException ex) {
                        ex.printStackTrace();
                } catch (IOException ex) {
                        ex.printStackTrace();
		} finally {
            		// When HttpClient instance is no longer needed,
            		// shut down the connection manager to ensure
            		// immediate deallocation of all system resources
            		httpclient.getConnectionManager().shutdown();
        	}
		return null;
	}
	public byte[] execScript(String nodeID, String data_id, String scriptID, String configurationID){
		return execScript(nodeID, "",data_id, scriptID, configurationID);
	}
	public byte[] execScript(String nodeID, String data_id, String scriptID){
		return execScript(nodeID, data_id, scriptID, "");
	}
}
